package com.lzhl.buildjar.util;

import com.lzhl.buildjar.ui.support.AutoFill;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 李柱良(@柱子的日月)
 * @date 2015/11/25
 */
public class FileUtils {

    private static String FILENAME_REGEX =
            "(?!((^(con)$)|^(con)//..*|(^(prn)$)|^(prn)//..*|(^(aux)$)|^(aux)//..*|(^(nul)$)|^(nul)//..*|(^(com)[1-9]$)|^(com)[1-9]//..*|(^(lpt)[1-9]$)|^(lpt)[1-9]//..*)|^//s+|.*//s$)(^[^/////////://*//?///\"//<//>//|]{1,255}$)";

    public static void explorer(File file, boolean select) {
        if(file == null) {
            return;
        }

        try {
            String command = "explorer ";
            if(select) {
                command += "/select, ";
            }
            command += file.getAbsolutePath();
            Runtime.getRuntime().exec(command);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }

    /** 复制文件
    * @param sourceFile
    * @param targetFile
    * @throws IOException
    */
    public static void copyFile(File sourceFile, File targetFile) throws IOException {
        BufferedInputStream inBuff = null;
        BufferedOutputStream outBuff = null;
        try {
            //新建文件输入流并对它进行缓冲
            inBuff = new BufferedInputStream(new FileInputStream(sourceFile));

            //新建文件输出流并对它进行缓冲
            outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
            //缓冲数组
            byte[] b = new byte[1024 * 5];
            int len;
            while ((len = inBuff.read(b)) != -1) {
                outBuff.write(b, 0, len);
            }
            //刷新此缓冲的输出流
            outBuff.flush();
        } finally {
            //关闭流
            if (inBuff != null)
                inBuff.close();
            if (outBuff != null)
                outBuff.close();
        }
    }

    /** 复制文件夹
     * @param sourceDir
     * @param targetDir
     * @throws IOException
     */
    public static void copyDirectiory(String sourceDir, String targetDir) throws IOException {
        //新建目标目录
        (new File(targetDir)).mkdirs();
        //获取源文件夹当前下的文件或目录
        File[] file = (new File(sourceDir)).listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                //源文件
                File sourceFile = file[i];
                //目标文件
                File targetFile = new File(new File(targetDir).getAbsolutePath() + File.separator + file[i].getName());
                copyFile(sourceFile, targetFile);
            }
            if (file[i].isDirectory()) {
                //准备复制的源文件夹
                String dirl = sourceDir + "/" + file[i].getName();
                //准备复制的目标文件夹
                String dir2 = targetDir + "/" + file[i].getName();
                copyDirectiory(dirl, dir2);
            }
        }
    }

    /**
    *递归删除目录下的所有文件及子目录下所有文件
    * @param dir 将要删除的文件目录
    * @return boolean Returns "true" if all deletions were successful.
    *         If a deletion fails, the method stops attempting to
    *         delete and returns "false".
    */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] childrens = dir.list();
            //递归删除目录中的子目录下
            for (String aChildren : childrens) {
                boolean success = deleteDir(new File(dir, aChildren));
                if (!success) {
                    return false;
                }
            }
        }
        //目录此时为空，可以删除
        return dir.delete();
    }

    public static List<String> loadFile(String filepath) {
        List<String> lines = new ArrayList<String>();

        File file = new File(filepath);
        if(file.isFile()) {
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
                String line;
                while ((line = reader.readLine()) != null) {
                    line = line.trim();
                    if(line.length() <= 0) {
                        continue;
                    }

                    lines.add(line);
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            finally {
                if(reader != null) {
                    try {
                        reader.close();
                    } catch (IOException ignore) {
                    }
                }
            }
        }

        return lines;
    }

    public static void saveFile(List<String> lines, String filepath) {
        PrintWriter writer = null;
        try {
            writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(filepath), "UTF-8"));
            for (String line : lines) {
                writer.println(line);
            }
            writer.flush();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            if(writer != null) {
                writer.close();
            }
        }
    }

    public static void saveFile(String content, String filepath) {
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filepath), "UTF-8"));
            writer.write(content);
            writer.flush();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            if(writer != null) {
                try {
                    writer.close();
                } catch (IOException ignore) {
                }
            }
        }
    }

    public static File getFile(File rootFile, String filePath) {
        String path = rootFile.getAbsolutePath();
        filePath = filePath.trim();
        if(filePath.startsWith(File.separator)) {
            path += filePath;
        }
        else {
            path += File.separator+filePath;
        }
        return new File(path);
    }


    public static boolean isValidFileName(String fileName) {
        if (fileName == null || fileName.length() > 255) {
            return false;
        }
        else {
            return fileName.matches(FILENAME_REGEX);
        }
    }

    //******************************************************************************************************************


    /**
     * 按行读取文本文件
     *
     * @param filename 文件名
     *
     * @return 行数据列表
     */
    public static List<String> readTextFile(String filename) {
        return readTextFile(filename, false);
    }

    /**
     * 按行读取文本文件
     *
     * @param filename 文件名
     * @param includeEmpty 是否包含空行
     *
     * @return 行数据列表
     */
    public static List<String> readTextFile(String filename, boolean includeEmpty) {
        return readTextFile(filename, "UTF-8", includeEmpty);
    }

    /**
     * 读取文本文件
     *
     * @param filename 文件名
     * @param encoding 文件编码
     * @param includeEmpty 是否包含空行
     *
     * @return 行数据列表
     */
    public static List<String> readTextFile(String filename, String encoding, boolean includeEmpty) {
        List<String> lines = new LinkedList<String>();

        File file = new File(filename);
        if(!file.exists()) {
//            LogUtils.warn("文件" + filename + "不存在。");
            return lines;
        }

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(filename), encoding));
            String line;
            while((line = reader.readLine()) != null){
                if(!includeEmpty) {
                    line = line.trim();
                    if(line.length() == 0) {
                        continue;
                    }
                }

                lines.add(line);
            }
        }
        catch (Exception e) {
//            LogUtils.error("文件" + filename + "读取失败。", e);
        }
        finally {
            if(reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return lines;
    }

    /**
     * 保存文本文件
     *
     * @param lines 文件内容
     * @param filename 文件名
     */
    public static boolean saveTextFile(List<String> lines, String filename) {
        return saveTextFile(lines, filename, "UTF-8");
    }

    /**
     * 保存文本文件
     *
     * @param lines 文件内容
     * @param filename 文件名
     * @param encoding 文件编码
     */
    public static boolean saveTextFile(List<String> lines, String filename, String encoding) {
        PrintWriter writer = null;
        try {
            writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(filename), encoding));
            for(String line : lines){
                if (line != null) {
                    writer.println(line);
                }
            }
            writer.flush();

            return true;
        }
        catch (Exception e) {
//            LogUtils.error("文件 " + filename + " 保存失败。", e);
        }
        finally {
            if(writer != null) {
                writer.close();
            }
        }

        return false;
    }

    //******************************************************************************************************************

    public static LinkedList<String> getLastClasses(AutoFill autoFill) {
        LinkedList<String> classes = new LinkedList<String>();

        File dir = autoFill.getClasspath();
        fillLastClasses(autoFill, dir);
        autoFill.count();

        String classPath = dir.getAbsolutePath();
        if(!classPath.endsWith(File.separator)) {
            classPath += File.separator;
        }

        for(File file : autoFill.getFiles()) {
            String item = file.getAbsolutePath().substring(classPath.length());
            classes.add(item);
        }

        return classes;
    }

    private static void fillLastClasses(AutoFill autoFill, File dir) {
        if(!dir.isDirectory()) {
            return;
        }
        File[] files = dir.listFiles();
        if(files == null) {
            return;
        }

        String classPath = autoFill.getClasspath().getAbsolutePath();
        String packageName = dir.getAbsolutePath().substring(classPath.length());
        if(packageName.startsWith(File.separator)) {
            packageName = packageName.substring(1);
        }
        packageName = packageName.toLowerCase();

        for(File file : files) {
            if(file.isDirectory()) {
                fillLastClasses(autoFill, file);
            }
            else if(file.isFile()) {
                autoFill.addFile(file, packageName);
            }
        }
    }

}
